package com.fourforfo.fourmall.auth.web;

import com.alibaba.fastjson.TypeReference;
import com.fourforfo.common.utils.R;
import com.fourforfo.common.vo.MemberRespVO;
import com.fourforfo.fourmall.auth.feign.MemberFeignService;
import com.fourforfo.fourmall.auth.vo.UserLoginVO;
import com.xxl.sso.core.conf.Conf;
import com.xxl.sso.core.login.SsoWebLoginHelper;
import com.xxl.sso.core.store.SsoLoginStore;
import com.xxl.sso.core.store.SsoSessionIdHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * sso server (for web)
 *
 * @author xuxueli 2017-08-01 21:39:47
 */
@Controller
public class XxlSsoWebController {


    @Autowired
    MemberFeignService memberFeignService;

    @RequestMapping("/index")
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);

        if (xxlUser == null) {
            return "redirect:/login";
        } else {
            model.addAttribute(Conf.SSO_USER, xxlUser);
            return "index";
        }
    }

    /**
     * @Description: 供client的xxlFilter获取获取xxlUser信息
     * @Param: [request, response]
     * @return: java.lang.String
     * @Author: fourforfo
     * @Date: 2022/8/22
     */
    @GetMapping(Conf.SSO_GET_USER_INFO)
    public String getUserInfo(HttpServletRequest request, HttpServletResponse response){
        //根据sso-server域名下的cookie获取xxlUser信息
        // login check
        return "redirect:http://auth.fourmall.com/get_sessionId";
    }

    @ResponseBody
    @GetMapping("get_sessionId")
    public String getSessionId(HttpServletRequest request,HttpServletResponse response){


        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);
        String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);

        return sessionId;
    }

    /**
    * @Description: 获取xxlUser信息
    * @Param: [request, response]
    * @return: java.lang.String
    * @Author: fourforfo
    * @Date: 2022/8/22
    */
    @GetMapping(Conf.SSO_USER_INFO)
    public String userinfo(HttpServletRequest request, HttpServletResponse response){
        //根据sso-server域名下的cookie获取xxlUser信息
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);

        String queryString = request.getQueryString();
        //redirect_url= 这个字符串后面的为完整的重定向url
        String redirectUrl = null;
        if(queryString!=null&&queryString.contains(Conf.REDIRECT_URL+"=")){
            redirectUrl = queryString.trim().substring(Conf.REDIRECT_URL.length()+1);
        }
        if (xxlUser != null) {

            // success redirect
            if (redirectUrl!=null && redirectUrl.trim().length()>0) {
                //在redirectUrl上拼上sessionId信息再跳转
                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                if(redirectUrl.contains("?")){
                    redirectUrl = redirectUrl + "&" + Conf.SSO_SESSIONID + "=" + sessionId;
                }else{
                    redirectUrl = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
                }
                request.setAttribute(Conf.SSO_USER, xxlUser);
                return "redirect:" + redirectUrl;
            }
        }
        //xxlUser为空说明当前浏览器是未登录的
        String suffix = Conf.IS_ALREADY_GET_USERINFO +"=" +Conf.ALREADY_GET_USERINFO;
        if (redirectUrl!=null && redirectUrl.trim().length()>0) {
            //如果链接中包含 ? 则用 & 连接后面的参数，否则用 ? 连接
            redirectUrl = "redirect:"+redirectUrl+(redirectUrl.contains("?")?"&":"?")+suffix;
        }else{
            redirectUrl = "redirect:http://fourmall.com?"+suffix;
        }
        return redirectUrl;
    }

    /**
     * Login page
     *
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(Conf.SSO_LOGIN)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);

        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
        //保存一下除redirect_url外的其他参数
        String queryString = request.getQueryString();
        String parameterStr = ""; //按 &str=a&str1=b&str2=c 这样的格式拼接
        if(!StringUtils.isEmpty(queryString)){
            String[] strings = queryString.split("&");
            for (String s : strings) {
                if(!s.contains(Conf.REDIRECT_URL)){
                    parameterStr = parameterStr + "&" + s;
                }
            }
        }

        if (xxlUser != null) {

            // success redirect
            if (redirectUrl!=null && redirectUrl.trim().length()>0) {

                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId + parameterStr;
                request.setAttribute(Conf.SSO_USER, xxlUser);
                return "redirect:" + redirectUrlFinal;
            } else {
//                attributes.addFlashAttribute("",xxlUser);
//                model.addAttribute(Conf.REDIRECT_URL,redirectUrl);
                return "redirect:http://fourmall.com";
            }
        }

        model.addAttribute(Conf.REDIRECT_URL,redirectUrl);

        model.addAttribute("msg", request.getParameter("errorMsg"));

        return "login";
    }

    /**
     * Login
     *
     * @param request
     * @param redirectAttributes
     * @param vo
     * @return
     */
    @RequestMapping("/doLogin")
    public String doLogin(HttpServletRequest request,
                        HttpServletResponse response,
                        RedirectAttributes redirectAttributes,
                        UserLoginVO vo,
                        String ifRemember) {

        //是否记住密码
        boolean ifRem = (ifRemember!=null&&"on".equals(ifRemember))?true:false;

        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);

        // valid login
        R r = memberFeignService.login(vo);

        if (r.getCode() != 0) {
            redirectAttributes.addFlashAttribute("msg", r.getMsg());
            //获取原地址，登录失败就返回原地址http://auth.fourmall.com/login?redirect_url={}
            String referer = request.getHeader("referer");
            return "redirect:"+referer;
        }

        //成功
        MemberRespVO respVO = r.getData(new TypeReference<MemberRespVO>() {});


        return loginSucess(response, ifRem, redirectUrl, respVO);

    }

    /**
     * 登录成功后生成sessionId并返回重定向地址
     * @param response
     * @param ifRem 是否记住密码
     * @param redirectUrl 重定向地址
     * @param respVO 登录成功后从远程服务返回的用户信息
     * @return 重定向地址
     */
    protected static String loginSucess(HttpServletResponse response, boolean ifRem, String redirectUrl, MemberRespVO respVO) {
        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        xxlUser.setUserid(String.valueOf(respVO.getId()));
        xxlUser.setUsername(respVO.getNickname());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        xxlUser.setExpireMinute(SsoLoginStore.getRedisExpireMinute());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());
        xxlUser.setIntegration(respVO.getIntegration());


        // 2、make session id
        String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);

        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem);

        // 4、return, redirect sessionId
        if(redirectUrl == null || redirectUrl.trim().length()<=0){
            redirectUrl = "http://fourmall.com";
        }
        String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
        return "redirect:" + redirectUrlFinal;
//        if (redirectUrl !=null && redirectUrl.trim().length()>0) {
//            String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
//            return "redirect:" + redirectUrlFinal;
//        } else {//redirectUrl为空表示是从
//            return "redirect:" + "http://fourmall.com";
//        }
    }

    /**
     * Logout
     *
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(Conf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {

        // logout
        SsoWebLoginHelper.logout(request, response);


        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);

        redirectAttributes.addAttribute(Conf.REDIRECT_URL, redirectUrl);
        //已经访问过sso-server
        redirectAttributes.addAttribute(Conf.IS_ALREADY_GET_USERINFO,Conf.ALREADY_GET_USERINFO);
        return "redirect:" + redirectUrl;
    }


}
